package ar.edu.utn.frsf.tpae.a2012.g05.entity;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name = "cta")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "cta_tipo", discriminatorType = DiscriminatorType.INTEGER)
public abstract class Cuenta {
	public static Integer CUENTA_CORRIENTE = 1;
	public static Integer CAJA_DE_AHORRO = 2;
	
	@Id @Column(name = "cta_id") @GeneratedValue(strategy = GenerationType.IDENTITY)
	protected Integer id;
	
	@Column(name = "cta_nro", nullable = false, unique = true)
	protected Integer numero;
	
	@Column(name = "cta_fech_ape", nullable = false, unique = true)
	protected Date fechaApertura;
	
	@Column(name = "cta_sdo_act", nullable = false, unique = true)
	protected BigDecimal saldoActual;
	
	@OneToMany(cascade = CascadeType.ALL, mappedBy = "cuenta")
    protected List<Movimiento> movimientos;
    
    @ManyToOne
    @JoinColumn(name="cta_cli_id")
    protected Cliente cliente;
	
	@Column(name = "cta_tipo", nullable = false, unique = true)
	protected Integer tipoCuenta;
	
	@Transient
	protected String DescripcionCuenta;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Integer getNumero() {
		return numero;
	}

	public void setNumero(Integer numero) {
		this.numero = numero;
	}

	public Date getFechaApertura() {
		return fechaApertura;
	}

	public void setFechaApertura(Date fechaApertura) {
		this.fechaApertura = fechaApertura;
	}

	public BigDecimal getSaldoActual() {
		return saldoActual;
	}

	public void setSaldoActual(BigDecimal saldoActual) {
		this.saldoActual = saldoActual;
		this.saldoActual.setScale(2);
	}

	public Integer getTipoCuenta() {
		return tipoCuenta;
	}

	public void setTipoCuenta(Integer tipoCuenta) {
		this.tipoCuenta = tipoCuenta;
	}
	
	public List<Movimiento> getMovimientos() {
		return movimientos;
	}

	public void setMovimientos(List<Movimiento> movimientos) {
		this.movimientos = movimientos;
	}
	
	public void addMovimiento(Movimiento movimiento){
		this.movimientos.add(movimiento);
	}

	public Cliente getCliente() {
		return cliente;
	}

	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}
	

	public String getDescripcionCuenta() {
		return DescripcionCuenta;
	}

	public void setDescripcionCuenta(String descripcionCuenta) {
		DescripcionCuenta = descripcionCuenta;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
//		result = prime * result
//				+ ((fechaApertura == null) ? 0 : fechaApertura.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((numero == null) ? 0 : numero.hashCode());
		result = prime * result
				+ ((saldoActual == null) ? 0 : saldoActual.hashCode());
		result = prime * result
				+ ((tipoCuenta == null) ? 0 : tipoCuenta.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cuenta other = (Cuenta) obj;
//		if (fechaApertura == null) {
//			if (other.fechaApertura != null)
//				return false;
//		} else if (!fechaApertura.equals(other.fechaApertura))
//			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (numero == null) {
			if (other.numero != null)
				return false;
		} else if (!numero.equals(other.numero))
			return false;
		if (saldoActual == null) {
			if (other.saldoActual != null)
				return false;
		} else if (!saldoActual.equals(other.saldoActual))
			return false;
		if (tipoCuenta == null) {
			if (other.tipoCuenta != null)
				return false;
		} else if (!tipoCuenta.equals(other.tipoCuenta))
			return false;
		return true;
	}
	
	public String toString() {
		return toFullString();
	}
	
	public String toFullString() {
		StringBuilder result = new StringBuilder();
		String newLine = System.getProperty("line.separator");

		result.append(this.getClass().getName() + "{");
		result.append(newLine);

		Field[] fields = this.getClass().getDeclaredFields();

		for (Field field : fields) {
			result.append("  ");
			try {
				result.append(field.getName());
				result.append(": ");
				result.append(field.get(this));
			} catch (IllegalAccessException ex) {
				System.out.println(ex);
			}
			result.append(newLine);
		}
		result.append("}");

		return result.toString();
	}
	
}
